import { _decorator, Component, director, instantiate, Node, Prefab } from "cc";
import { ApiMsgEnum } from "../Common";
import { IRoom } from "../Common/Api";
import { IMsgGameStart, IMsgRoomClose, IMsgRoomInfo } from "../Common/Msg";
import { SceneEnum } from "../Enum";
import DataManager from "../Global/DataManager";
import { NetworkManager } from "../Global/NetworkManager";
import { PlayerManager } from "../UI/PlayerManager";
import { deepClone } from "../Utils";
const { ccclass, property } = _decorator;

@ccclass("RoomManager")
export class RoomManager extends Component {
    @property(Node)
    playerContiner: Node;
    @property(Prefab)
    playerPrefab: Prefab;
    @property(Node)
    startBtn: Node;

    onLoad() {
        this.startBtn.active = false;
        NetworkManager.Instance.listenMsg(
            ApiMsgEnum.MsgRoomInfo,
            this.renderPlayers,
            this
        );
        NetworkManager.Instance.listenMsg(
            ApiMsgEnum.MsgGameStart,
            this.handleGameStart,
            this
        );
        NetworkManager.Instance.listenMsg(
            ApiMsgEnum.MsgRoomClose,
            this.handleLeaveRoom,
            this
        );
    }

    start() {
        this.renderBtns(DataManager.Instance.roomInfo);
        this.renderPlayers({ room: DataManager.Instance.roomInfo });
    }

    protected onDestroy(): void {
        NetworkManager.Instance.unlistenMsg(
            ApiMsgEnum.MsgRoomInfo,
            this.renderPlayers,
            this
        );
        NetworkManager.Instance.unlistenMsg(
            ApiMsgEnum.MsgGameStart,
            this.handleGameStart,
            this
        );
        NetworkManager.Instance.unlistenMsg(
            ApiMsgEnum.MsgRoomClose,
            this.handleLeaveRoom,
            this
        );
    }

    renderBtns(room: IRoom) {
        if (room.masterId === DataManager.Instance.myPlayerId) {
            this.startBtn.active = true;
        }
    }

    renderPlayers({ room: { players: list } }: IMsgRoomInfo) {
        for (const node of this.playerContiner.children) {
            node.active = false;
        }

        while (this.playerContiner.children.length < list.length) {
            const node = instantiate(this.playerPrefab);
            node.setParent(this.playerContiner);
            node.active = false;
        }

        for (let i = 0; i < list.length; i++) {
            const data = list[i];
            const node = this.playerContiner.children[i];
            const pm = node.getComponent(PlayerManager);
            pm.init(data);
        }
    }

    async handleLeave() {
        const { success, res, error } = await NetworkManager.Instance.callApi(ApiMsgEnum.ApiRoomLeave, {})
        if (!success) {
            console.log(error)
            return;
        }
        this.handleLeaveRoom(null);
    }

    handleLeaveRoom(data: IMsgRoomClose) {
        if (data) {
            console.log(data?.msg)
        }
        DataManager.Instance.roomInfo = null
        director.loadScene(SceneEnum.Hall)
    }

    async handleStart() {
        const { success, res, error } = await NetworkManager.Instance.callApi(ApiMsgEnum.ApiGameStart, {})
        if (!success) {
            console.log(error)
            return;
        }
    }

    handleGameStart({ state }: IMsgGameStart) {
        DataManager.Instance.state = state;
        DataManager.Instance.lastState = deepClone(DataManager.Instance.state);
        console.log(state.actors)
        director.loadScene(SceneEnum.Battle)
    }
}
